package com.jingxuan.controller;

import com.jingxuan.common.annotation.NoAuth;
import com.jingxuan.common.result.Result;
import com.jingxuan.common.result.ResultCode;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.lang.NonNull;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping("/files")
public class FileController {

    @Value("${file.upload-dir:uploads/}")
    private String uploadDir;

    @PostMapping("/upload")
    @NoAuth
    public Result<String> upload(@RequestParam("file") MultipartFile file, @NonNull HttpServletRequest request) {
        log.info("开始文件上传，文件名: {}, 大小: {}, 内容类型: {}",
                 file.getOriginalFilename(), file.getSize(), file.getContentType());
        
        if (file.isEmpty()) {
            log.error("文件为空");
            return Result.error(ResultCode.PARAM_ERROR, "文件为空");
        }

        try {
            // 确保上传目录存在
            String path = uploadDir;
            log.info("配置的上传目录: {}", path);
            
            // 如果是相对路径，基于 user.dir
            File dir = new File(path);
            if (!dir.isAbsolute()) {
                path = System.getProperty("user.dir") + File.separator + path;
                dir = new File(path);
                log.info("转换为绝对路径: {}", path);
            }

            log.info("最终上传目录: {}", dir.getAbsolutePath());
            
            if (!dir.exists()) {
                boolean created = dir.mkdirs();
                if (created) {
                    log.info("创建上传目录: {}", dir.getAbsolutePath());
                } else {
                    log.error("创建上传目录失败: {}", dir.getAbsolutePath());
                    return Result.error(ResultCode.INTERNAL_ERROR, "创建上传目录失败");
                }
            }

            // 检查目录是否可写
            if (!dir.canWrite()) {
                log.error("上传目录不可写: {}", dir.getAbsolutePath());
                return Result.error(ResultCode.INTERNAL_ERROR, "上传目录不可写，请检查权限设置");
            }

            // 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String extension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            String fileName = UUID.randomUUID().toString() + extension;
            log.info("生成的文件名: {}", fileName);

            // 保存文件
            File dest = new File(dir, fileName);
            log.info("目标文件路径: {}", dest.getAbsolutePath());
            
            file.transferTo(dest);
            log.info("文件保存成功: {}", dest.getAbsolutePath());
            
            // 验证文件是否真的存在
            if (dest.exists()) {
                log.info("文件验证成功，大小: {} bytes", dest.length());
            } else {
                log.error("文件验证失败，文件不存在: {}", dest.getAbsolutePath());
            }

            // 返回访问URL
            String baseUrl = ServletUriComponentsBuilder.fromRequestUri(request)
                    .replacePath(null)
                    .build()
                    .toUriString();
            if (!StringUtils.hasText(baseUrl)) {
                baseUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
            }

            // 构造文件访问URL，注意不包含context-path，因为静态资源是直接映射的
            String fileUrl = baseUrl + "/uploads/" + fileName;
            log.info("文件上传成功，返回URL: {}", fileUrl);
            log.info("配置的上传目录: {}, 实际文件路径: {}", uploadDir, dest.getAbsolutePath());
            return Result.success("上传成功", fileUrl);

        } catch (IOException e) {
            log.error("文件上传失败", e);
            return Result.error(ResultCode.INTERNAL_ERROR, "文件上传失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("文件上传出现未知错误", e);
            return Result.error(ResultCode.INTERNAL_ERROR, "文件上传出现未知错误: " + e.getMessage());
        }
    }

    /**
     * 删除文件
     * @param fileUrl 文件URL
     * @return 删除结果
     */
    public boolean deleteFile(String fileUrl) {
        if (fileUrl == null || fileUrl.isEmpty()) {
            log.info("文件URL为空，无需删除");
            return true;
        }

        try {
            // 从URL中提取文件名
            // URL格式通常是: http://domain:port/uploads/filename.ext
            String fileName = "";
            if (fileUrl.contains("/uploads/")) {
                fileName = fileUrl.substring(fileUrl.lastIndexOf("/uploads/") + 9);
            } else {
                log.warn("无法从URL中提取文件名: {}", fileUrl);
                return false;
            }

            // 构建文件路径
            String path = uploadDir;
            File dir = new File(path);
            if (!dir.isAbsolute()) {
                path = System.getProperty("user.dir") + File.separator + path;
                dir = new File(path);
            }

            File fileToDelete = new File(dir, fileName);
            
            if (fileToDelete.exists()) {
                boolean deleted = fileToDelete.delete();
                if (deleted) {
                    log.info("文件删除成功: {}", fileToDelete.getAbsolutePath());
                    return true;
                } else {
                    log.error("文件删除失败: {}", fileToDelete.getAbsolutePath());
                    return false;
                }
            } else {
                log.info("文件不存在，无需删除: {}", fileToDelete.getAbsolutePath());
                return true;
            }
        } catch (Exception e) {
            log.error("删除文件时出现错误: {}", fileUrl, e);
            return false;
        }
    }
}